package controlador;

import java.util.List;

import modelo.Especificacion;
import modelo.Modelo;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.event.rule.DebugAgendaEventListener;
import org.drools.event.rule.DebugWorkingMemoryEventListener;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;

public class Controlador {

	private static Controlador instance = new Controlador();

	private Seleccion seleccion;
	private Especificacion especificacion;
	
	private Controlador() {
		seleccion = new Seleccion();
		especificacion = new Especificacion();
	}
	
	public static Controlador getInstance() {
		return instance;
	}

	private KnowledgeBase cargarReglas() {

		KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
		kbuilder.add(ResourceFactory.newClassPathResource("reglas.drl"), ResourceType.DRL);

		KnowledgeBuilderErrors errors = kbuilder.getErrors();

		if (errors.size() > 0) {
			for (KnowledgeBuilderError error : errors) {
				System.err.println(error);
			}
			throw new IllegalArgumentException("Could not parse knowledge.");
		}

		KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
		kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());

		return kbase;
	}

	private StatefulKnowledgeSession crearSesion(KnowledgeBase kbase) {
		return kbase.newStatefulKnowledgeSession();
	}

	public void ejecutarReglas() {

		KnowledgeBase base = cargarReglas();
		StatefulKnowledgeSession session = crearSesion(base);

		KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(session, "log/selectorpcs");
		session.addEventListener( new DebugAgendaEventListener() );
		session.addEventListener( new DebugWorkingMemoryEventListener() );
		
		session.insert(seleccion);
		session.insert(especificacion);

		session.update(session.getFactHandle(seleccion), seleccion);
		session.update(session.getFactHandle(especificacion), especificacion);

		session.fireAllRules();

		logger.close();

		session.dispose();
	}

	public void limpiar() {
		seleccion = new Seleccion();
		especificacion = new Especificacion();
	}

	public Seleccion getSeleccion() {
		return seleccion;
	}

	public List<Modelo> getRecomendacion() {
		return especificacion.obtenerRecomendacion();
	}
}
